//  AtomicMap

use std::{collections::HashMap, fmt,sync::{atomic::{AtomicI64,Ordering},
                  Arc}
};

use anyhow::{Result};
// metrix   系统里， 往往是很清楚， 有多少个  页面需要监控。

#[derive(Debug)]
pub struct AmapMetrics{
    data: Arc<HashMap<&'static str,AtomicI64>>,
}

// 实现new 时， 不能是空的， 所以初始化时， 就要知道 , key 要先知道的。
impl AmapMetrics {
    pub fn new (metric_names: &[&'static str]) ->Self {
        let map = metric_names
        .iter()
        .map(|&name|(name, AtomicI64::new(0)))
        .collect();
    AmapMetrics{
        data: Arc::new(map),
    }
    }


    pub fn inc(&self, key: impl AsRef<str>) ->Result<()> {
        let key  = key.as_ref();
        let counter = self.data.get(key).ok_or_else(|| anyhow::anyhow!("key {} not found", key))?;
        counter.fetch_add(1, Ordering::Relaxed);
        Ok(())
    }
}

impl Clone for AmapMetrics {
    fn clone(&self) -> Self {
        AmapMetrics {
            data: Arc::clone(&self.data),
        }
    }
}

impl fmt::Display for AmapMetrics {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for (key,value) in self.data.iter() {
            writeln!(f, "{},{}", key, value.load(Ordering::Relaxed))?;
           }
    
           Ok(())
    }
}

